var DsModule = {
    root: window.root == null ? "/" : window.root,
    modulePath: "/", //公共的模块路径
    cacheCss: [],
    cacheHtml: [],
    cacheJs: [],
    importJs: [],//是否已经引入过js
    moduleId: {}, //id 对应模块
    handlers: {},//路径处理器
    controller: [],
    ieVersion: null,
    protocolFile: false,
    defaultEvent:{},//默认事件绑定,
    debug:false,
    moduleLoad:{},//存储是否模块已加载
    version:"0.0.0",//设置版本
    bindData:{},//页面绑定数据，class对应处理的fun
    addBindData:function(className,fun){
        DsModule.bindData[className]=fun;
    },
    addEvent:function(type,className,fun){
        if(DsModule.defaultEvent[type]==null){
            DsModule.defaultEvent[type]={};
        }
        if(DsModule.defaultEvent[type][className]!=null){
            throw Error(type+":"+className+",出现事件覆盖");
        }
        DsModule.defaultEvent[type][className]=fun;
    },
    isPc:function(){
        var userAgentInfo = navigator.userAgent;
        var Agents = ["Android", "iPhone",
            "SymbianOS", "Windows Phone",
            "iPad", "iPod"];
        var flag = true;
        for (var v = 0; v < Agents.length; v++) {
            if (userAgentInfo.indexOf(Agents[v]) > 0) {
                flag = false;
                break;
            }
        }
        return flag;
    },
    log:{
        debug:function(content,_this){
            if(DsModule.debug){
                console.log(content);
            }
        },
        pathDebug:function(content){
            if(DsModule.debug) {
                console.log("路径跳转[" + content + "]");
            }
        }
    },
    eventListener:function(type){
        return function(e){
            var element=e.target;
            if(element.getAttribute==null){
                return;
            }
            var defaultEvent={}
            if(DsModule.defaultEvent[type]!=null){
                defaultEvent=DsModule.defaultEvent[type];
            }
            var events=element.getAttribute("event");
            var classNames = (events||element.className).split(' ');
            for(var i=0;i<classNames.length;i++){
                if(defaultEvent[classNames[i]]!=null){
                    var _this=null;
                    var parent= element.parentNode||element.parentElement;
                    while(true){
                        if(parent==null){
                            break;
                        }
                        var id=parent.getAttribute("ds-free-module-id");
                        if(id!=null){
                            _this=DsModule.getModule(id);
                            break;
                        }
                        parent=parent.parentNode||parent.parentElement;
                    }
                    defaultEvent[classNames[i]].call(element,e,_this);
                    return;
                }
            }
        }
    },
    dataListener:function(module){
        if(module.dataListenerFlag){
            return;
        }
        module.dataListenerFlag=true;
        try {
            var handler= {
                get: function (target, key) {
                    return target[key];
                },
                set: function (target, key, value) {
                    if (target[key] != value) {
                        if (value&&typeof value == "object") {
                            target[key] = new Proxy(value, handler);
                            if(module.autoReload){
                                module.reload();
                            }
                            return true;
                        }
                        target[key] = value;
                        if(module.autoReload) {
                            module.reload();
                        }
                    }
                    return true;
                }
            }
            var proxyFor=function(m,data,key1){
                if (data&&typeof data == "object") {
                    for(var key in data){
                        proxyFor(data,data[key],key);
                    }
                }
                if(data!=null){
                    m[key1]=new Proxy(data,handler);
                }
            }
            proxyFor(module,module.data,"data");
        }catch(e){
            module._oldData=DsModule.copy(module.data);
            module.setInterval('_dataListener',function(){
                if(JSON.stringify(module._oldData)!=JSON.stringify(module.data)){
                    module._oldData=DsModule.copy(module.data);
                    if(module.autoReload){
                        module.reload();
                    }
                }
            },50)
        }

    },
    init: function (options) {
        if(options!=null&&options.debug){
            DsModule.debug=options.debug;
        }
        if (window.location.protocol == "file:") {
            DsModule.protocolFile = true;
        }
        var browser = navigator.appName;
        var b_version = navigator.appVersion;
        var version = b_version.split(";");
        var trim_Version = version[1].replace(/[ ]/g, "");
        if (browser == "Microsoft Internet Explorer" && trim_Version == "MSIE6.0") {
            DsModule.ieVersion = 6;
        } else if (browser == "Microsoft Internet Explorer" && trim_Version == "MSIE7.0") {
            DsModule.ieVersion = 7;
        } else if (browser == "Microsoft Internet Explorer" && trim_Version == "MSIE8.0") {
            DsModule.ieVersion = 8;
        }
        if (!document.getElementsByClassName) {
            document.getElementsByClassName = function (className, element) {
                var children = (element || document).getElementsByTagName('*');
                var elements = [];
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    var classNames = child.className.split(' ');
                    for (var j = 0; j < classNames.length; j++) {
                        if (classNames[j] == className) {
                            elements.push(child);
                            break;
                        }
                    }
                }
                return elements;
            };
        }
        //开启绑定事件
        window.addEventListener('click',DsModule.eventListener('click'));
        window.addEventListener('abort',DsModule.eventListener('abort'));
        window.addEventListener('blur',DsModule.eventListener('blur'));
        window.addEventListener('change',DsModule.eventListener('change'));
        window.addEventListener('dblclick',DsModule.eventListener('dblclick'));
        window.addEventListener('error',DsModule.eventListener('error'));
        window.addEventListener('focus',DsModule.eventListener('focus'));
        window.addEventListener('keydown',DsModule.eventListener('keydown'));
        window.addEventListener('keypress',DsModule.eventListener('keypress'));
        window.addEventListener('keyup',DsModule.eventListener('keyup'));
        window.addEventListener('load',DsModule.eventListener('load'));
        window.addEventListener('mousedown',DsModule.eventListener('mousedown'));
        window.addEventListener('mousemove',DsModule.eventListener('mousemove'));
        window.addEventListener('mouseout',DsModule.eventListener('mouseout'));
        window.addEventListener('mouseover',DsModule.eventListener('mouseover'));
        window.addEventListener('mouseup',DsModule.eventListener('mouseup'));
        window.addEventListener('reset',DsModule.eventListener('reset'));
        window.addEventListener('resize',DsModule.eventListener('resize'));
        window.addEventListener('select',DsModule.eventListener('select'));
        window.addEventListener('submit',DsModule.eventListener('submit'));
        window.addEventListener('unload',DsModule.eventListener('unload'));
    },
    _getResUrl: function (url) {
        var appendParams=function(url){
            var hashIndex=url.indexOf("#");
            var hash="";
            if(hashIndex!=-1){
                hash=url.substring(hashIndex,url.length);
                url=url.substring(0,hashIndex);
            }
            if(url.indexOf("?")==-1){
                return url+"?version="+DsModule.version+hash;
            }
            return url+"&version="+DsModule.version+hash;
        }
        if (url.indexOf("http://") == 0) {
            return appendParams(url);
        }
        if (url.indexOf("https://") == 0) {
            return appendParams(url);
        }
        if (DsModule.protocolFile) {
            if (DsModule.root) {
                var hrefStr = window.location.href;
                hrefStr = hrefStr.substring(0, hrefStr.lastIndexOf(DsModule.root));
                return hrefStr + DsModule.root + url.substring(1,url.length);
            }
            return appendParams(url);
        }
        if (!DsModule.root) {
            return appendParams(url);
        }
        return appendParams(DsModule.root + url);

    },
    _getRequest: function () {
        var xmlHttp = null;
        try {
            xmlHttp = new XMLHttpRequest();
        } catch (e) {
            try {
                xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                    console.error(e);
                }
            }
        }
        return xmlHttp;
    },
    resIndex: 0
    ,
    _getRes: function (url, callback) {
        if(DsModule.protocolFile){
            //本地文件暂时无法跨域加载
            return;
        }
        var xmlHttp = DsModule._getRequest();
        xmlHttp.open("GET", url, true);
        xmlHttp.setRequestHeader("Content-Type", "text/html");
        xmlHttp.onreadystatechange = function () {
            if ((xmlHttp.readyState == 4) && (xmlHttp.status == 200)) {
                callback(xmlHttp.responseText);
            }
        };
        xmlHttp.send(null);
    },
    _getModuleHtml: function (moduleName, html) {
        var index = html.indexOf("{{#" + moduleName + "}}") + 5 + moduleName.length;
        var endIndex = html.indexOf("{{/" + moduleName + "}}");
        var str = html.substring(index, endIndex);
        if (str == null) {
            throw new Error(moduleName + "：不存在当前资源文件中");
        }
        return str;
    },
    _stringToChildNodes: function (txt,module) {
        var objE = document.createElement("div");
        objE.setAttribute("ds-free-module-id",module.id);
        objE.innerHTML = txt;
        return objE;
    },
    handler: function (key, callback) {
        DsModule.handlers[key] = callback;
    },
    getParams: function (paramsStr) {
        var params = {};
        var strs = paramsStr.split("&");
        for (var i = 0; i < strs.length; i++) {
            params[strs[i].split("=")[0]] = decodeURIComponent(strs[i].split("=")[1]);
        }
        return params;
    },
    paramsToUrl: function (obj) {
        if (obj == null) {
            return "";
        }
        var paramsStr = "";
        var joinStr = "";
        for (var k in obj) {
            paramsStr += joinStr + k + "=" + encodeURIComponent(obj[k]);
            if (joinStr == "") {
                joinStr = "&";
            }
        }
        return paramsStr;
    },
    copy:function(obj){
        //判断拷贝的要进行深拷贝的是数组还是对象，是数组的话进行数组拷贝，对象的话进行对象拷贝
        var objClone = Array.isArray(obj) ? [] : {};
        //进行深拷贝的不能为空，并且是对象或者是
        if (obj && typeof obj === "object") {
            for (var key in obj) {
                if (obj.hasOwnProperty(key)) {
                    if (obj[key] && typeof obj[key] === "object") {
                        objClone[key] = DsModule.copy(obj[key]);
                    } else {
                        objClone[key] = obj[key];
                    }
                }
            }
        }
        return objClone;
    },


    /**
     * 可刷新，可跳转
     * @param url 不传值为刷新
     * @param obj
     */
    to: function (url, obj,reload) {
        if (url != null) {
            var params = "";
            if(obj!=null){
                for (var k in obj) {
                    params += "&" + k + "=" + obj[k];
                }
            }
            if(params!=""){
                if (url.indexOf("?") != -1) {
                    url += params;
                } else {
                    url += "?" + params.substring(1, params.length);
                }
            }
            window.location.hash = url;
            DsModule.log.pathDebug(url);
        }else{
            var hash=window.location.hash;
            DsModule.log.pathDebug(hash.substring(1,hash.length));
        }
        if (DsModule.handlers[url] != null) {
            DsModule.handlers[url](reload);
        } else {
            DsModule.toDefaultIndex(reload);
        }
    },

    /**
     * 获取路径和参数
     */
    getPath:function(){
        var hash = window.location.hash;
        if (hash == "") {
            return;
        }
        var path = hash.substring(1, hash.length);
        var paramsStr="";
        if (hash.indexOf("?") != -1) {
            path=hash.substring(1, hash.indexOf("?"));
            paramsStr = hash.substring(hash.indexOf("?")+1, hash.length);
        }
        var params = DsModule.getParams(paramsStr);
        return {"path":path,"params":params};
    },
    toDefaultIndex: function (reload) {
        var obj=DsModule.getPath();
        document.body.innerHTML = "";
        var m = new Module(obj.path);
        m.params = obj.params;
        m.load();
    }
    ,
    getModule: function (id) {
        return DsModule.moduleId[id];
    }
};
DsModule.init({debug:window.debug});


//跳转默认事件 hash 跳转地址  参数前缀 data-=""
DsModule.addEvent('click','e-go',function(e,_this){
    var obj=this;
    var url=obj.getAttribute("href");
    var reload=obj.getAttribute("reload");
    if(reload==null){
        reload=false;
    }else{
        reload=true;
    }
    var ab= obj.attributes;
    var param={};
    for(var i=0;i<ab.length;i++){
        var k=ab[i];
        if(k.name.startsWith("data-")){
            param[k.name.substring(5,k.name.length)]=k.value;
        }
    }
    DsModule.to(url,param,reload);
});



//页面绑定数据
DsModule.addEvent('change','e-bind',function(e,_this){
    var data=this.getAttribute("data-bind");
    if(this.tagName.toLowerCase()=="input"){
        var js="_this."+data+"='"+this.value+"';";//input 标签支持
        _this.debug("触发页面数据绑定到data:"+js);
        _this.modifyDataNoReload(function(){
            eval(js);
        });
    }else if(this.tagName.toLowerCase()=="select"){
        var v=null;
        if(this.multiple) {
            v=[];
            for(var i=0;i<this.length;i++){
                if(this.options[i].selected){
                    v.push(this.options[i].value);
                }
            }
        }else{
            v=this.value;
        }
        var js="_this."+data+"=v;";//select 标签支持
        _this.debug("触发页面数据绑定到data:"+js);
        _this.modifyDataNoReload(function(){
            eval(js);
        });
    }else if(this.tagName.toLowerCase()=="textarea"){
        var js="_this."+data+"='"+this.value+"';";//textarea 标签支持
        _this.debug("触发页面数据绑定到data:"+js);
        _this.modifyDataNoReload(function(){
            eval(js);
        });

    }


});
//数据绑定到页面
DsModule.addBindData('e-bind',function(data){
    var elements=document.getElementsByClassName("e-bind");
    for(var i=0;i<elements.length;i++){
        var element=elements[i];
        var dataBind=element.getAttribute("data-bind");
        if(!dataBind){
            continue;
        }
        var d=eval(dataBind);
        if(d==null||d==undefined){
            continue;
        }
        if(element.tagName.toLowerCase()=="input"){
            if(element.type=='checkbox'){
                var js=dataBind;
                var arr=eval(js);
                for(var j=0;j<arr.length;j++){
                    if(arr[j]==element.value){
                        element.checked='checked';
                        break;
                    }
                }
                continue;
            }
            if(element.type=='radio'){
                var js="element.value=="+dataBind;
                var flag= eval(js);
                if(flag){
                    element.checked='checked';
                }
                continue;
            }
            var js="element.value="+dataBind;
            eval(js);
        }else if(element.tagName.toLowerCase()=="select"){
            var js=dataBind;
            var obj=eval(js);
            if(obj instanceof Array){
                for(var i=0;i<element.length;i++){
                    if(obj.indexOf(element.options[i].value)!=-1){
                        element.options[i].selected="selected";
                    }
                }
            }else{
                element.value=obj;
            }
        }else if(element.tagName.toLowerCase()=="textarea"){
            var js="element.value="+dataBind;
            eval(js);
        }
    }
})




//跳转到当前模块的主页 index
DsModule.addEvent('click','e-go-index',function(e,_this){
    var obj=this;
    var hash = window.location.hash;
    var reload=obj.getAttribute("reload");
    if(reload==null){
        reload=false;
    }else{
        reload=true;
    }
    var url="";
    hash = hash.substring(1, hash.length);
    if(hash.indexOf("/")==-1){
        url+="/index";
    }else{
        url=hash.substring(0,hash.lastIndexOf("/"))+"/index";
    }
    var ab= obj.attributes;
    var param={};
    for(var i=0;i<ab.length;i++){
        var k=ab[i];
        if(k.name.startsWith("data-")){
            param[k.name.substring(5,k.name.length)]=k.value;
        }
    }
    DsModule.to(url,param,reload);
});



/**
 * js 执行在html中
 * @type {{exec: DsTemplate.exec}}
 */
var DsTemplate = {
    exec: function (html, data) {
        if (html == null) {
            return "";
        }
        if (data == null) {
            data = {};
        }
        html = html.replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/<js-code>/g, "<js>{</js>").replace(/<\/js-code>/g, "<js>}</js>");
        html = html.replace(/<\/js>/g, "\n<\/js>\n").replace(/<js>/g, "\n<js>\n");
        var htmls = html.split("\n");
        var resultHtml1 = null;
        var resultHtml = "var resultHtml1=\"\";\n";
        var jsFlag = false;
        for (var i = 0; i < htmls.length; i++) {
            var htmlData = htmls[i];
            if (htmlData.trim() == "") {
                continue;
            }
            if (htmlData.trim().indexOf('<js>') != -1) {
                jsFlag = true;
                continue;
            } else if (htmlData.trim().indexOf('</js>') != -1) {
                jsFlag = false;
                continue;
            }
            if (jsFlag) {
                resultHtml += htmlData + "\n";
            } else {
                htmlData = htmlData.replace(/\r/g, "").replace(/"/g, "\\\"").replace(/'/g, "\\\'");
                resultHtml += "resultHtml1+=\"" + htmlData + "\";\n";
            }
        }
        var regNotStart2 = /\$\{[A-Za-z0-9= \-\\()'?"\:\.@\s_\[\]]+}/g;
        var match2 = resultHtml.match(regNotStart2);
        if (match2 != null) {
            for (var i = 0; i < match2.length; i++) {

                resultHtml = resultHtml.replace(match2[i], ("\"+DsTemplate.format(" + (match2[i].substring(2, match2[i].length - 1)).replace(/\\'/g,"'").replace(/\\"/g,'"') + ")+\""));
                while (resultHtml.indexOf(match2[i]) != -1) {
                    resultHtml = resultHtml.replace(match2[i], ("\"+DsTemplate.format(" + (match2[i].substring(2, match2[i].length - 1)).replace(/\\'/g,"'").replace(/\\"/g,'"') + ")+\""));
                }
            }
        }
        eval(resultHtml);
        return resultHtml1;
    },
    format: function (data) {
        if (data!=null) {
            return data;
        }
        return "";
    }
};

/**
 * 模块定义加载
 * @param moduleName
 * @constructor
 */
var Module = function (modulePath,resComplete) {
    if (modulePath == null) {
        throw new Error("模块路径不能为空");
    }
    this.modulePath = DsModule.modulePath + modulePath;
    this.baseUrl = this.modulePath.substring(0, this.modulePath.lastIndexOf("/"));
    this.moduleName = this.modulePath.substring(this.modulePath.lastIndexOf("/") + 1, this.modulePath.length); //模块下面子模块
    this.resultHtml = null;
    this.resHtmlUrl = this.baseUrl + "/module.html"; //资源html 路径
    this.resJsUrl = this.baseUrl + "/" + this.moduleName + ".js"; //资源js 路径
    this.data = {};//数据
    this.proxyData=false;
    this.params = {};//url数据参数
    this.parentDom = null; //父级dom元素
    this.selfDom = null;//本元素dom
    this.resLoadSum = -1;// 资源加载总数
    this.resLoadCount = 0;// 资源加载数量
    this.importSum = -1;//依赖资源总数
    this.importCount = 0;//依赖加载数量
    this.id = null;
    this.loadCount = 0;//已经加载到页面次数
    this.loadCompleteFun = [];//加载到页面完成后执行的事件
    var _this=this;
    this.resCompleteFlag=false;//资源是否加载完成
    this.interval={};//存储定时器，保证一个模块只存在一个定时器
    this.timeout={};//存储定时器，保证一个模块只存在一个定时器
    this.dataListenerFlag=false;//是否已开启数据监听
    this.autoReload=true;//默认自动重新加载视图
    this.cacheDataFlag=false; //是否开启缓存data数据，只支持localStorage
    this.resComplete=function(){
        _this.resCompleteFlag=true;
        if(resComplete!=null){
            resComplete.call(_this);
        }
    };//资源加载完成后执行的事件
    this._load(); //只加载资源
};
//数据绑定到页面
Module.prototype.bind=function(data){
    for(var k in DsModule.bindData){
        DsModule.bindData[k].call(this,data);
    }
}

Module.prototype.setTimeout=function(key,callback,time){
    if(this.timeout[key]!=null){
        window.clearTimeout(this.timeout[key]);
        this.timeout[key]=null;
    }
    this.timeout[key]=window.setTimeout(function(){
        callback();
    },time);
}
Module.prototype.setInterval=function(key,callback,time){
    if(this.interval[key]!=null){
        window.clearInterval(this.interval[key]);
        this.interval[key]=null;
    }
    this.interval[key]=window.setInterval(function(){
        callback();
    },time);
}
Module.prototype.debug=function(content){
    DsModule.log.debug(content,this)
}

/**
 * 修改data数据不刷新页面
 */
Module.prototype.modifyDataNoReload=function(call){
    if(!this.autoReload){
        call.call(this);
        this.setCacheData();
        return;
    }
    if(this._oldData!=null){
        this.autoReload=false;
        call.call(this);
        this.setCacheData();
        this._oldData=DsModule.copy(this.data);
        this.autoReload=true;
        return;
    }
    this.autoReload=false;
    call.call(this);
    this.setCacheData();
    this.autoReload=true;
}

/**
 * 缓存的data
 */
Module.prototype.setCacheData=function(){
    if(this.cacheDataFlag){
        this.debug("触发自动缓存模块data");
        if(window.localStorage){
            window.localStorage.setItem(this.modulePath+this.id,JSON.stringify(this.data));
        }
    }
}
/**
 * 获取缓存的data
 */
Module.prototype.getCacheData=function(){
    if(window.localStorage){
        var dataStr= window.localStorage.getItem(this.modulePath+this.id);
        if(dataStr){
            return JSON.parse(dataStr);
        }
    }
    return null;
}
/**
 * 清除缓存
 */
Module.prototype.clearCacheData=function(){
    if(window.localStorage){
        window.localStorage.removeItem(this.modulePath+this.id);
    }
}

/**
 * 有依赖调用
 * @private
 */
Module.prototype._callJsObj = function () {
    if (this.import == null) {
        this._import([]);
    } else {
        this._import(this.import);
    }
}
/**
 * 把模块加载到父元素
 */
Module.prototype.load = function (id) {
    var _this = this;
    if (id != null) {
        if(DsModule.moduleId[id]!=null){
            DsModule.moduleId[id].remove();
        }
        _this.parentDom = document.getElementById(id);
        DsModule.moduleId[id] = this;
        _this.id = id;
    } else {
        _this.parentDom = document.body;
        if(_this.id==null){
            for(;;){
                id="module_"+(new Date().getTime())+Math.floor(Math.random()*1000);
                if(DsModule.moduleId[id]==null){
                    break;
                }
            }
            _this.id=id;
        }
        DsModule.moduleId[_this.id] = this;
    }

    var callback=function(){
        if (_this.init != null) {
            _this.init.call(_this);
        }
        var data=DsModule.copy(_this.data);
        _this._execFun(data);
    }
    if(_this.resCompleteFlag){
        callback();
    }else{
        _this.resComplete=function(){
            _this.resCompleteFlag=true;
            callback();
        }
    }
    return this;
};
/**
 * 计算依赖的文件数量
 * @param obj
 */
Module.prototype._eachImportCount = function (obj) {
    this.importSum++;
    if (obj.import != null) {
        for (var i = 0; i < obj.import.length; i++) {
            this._eachImportCount(obj.import[i]);
        }
    }
};

/**
 * jquery 对象只在当面模块生效
 * @param obj
 * @returns {jQuery}
 */
Module.prototype.$ = function (obj) {
    return obj==null? $(this.selfDom):$(this.selfDom).find(obj);
};




/**
 *循环导入依赖
 */
Module.prototype._eachImport = function (obj) {
    var _this = this;
    var callback = function () {
        _this.importCount++;
        if (_this.importSum == _this.importCount) {
            _this.debug("加载["+_this.modulePath+"]所有资源完成");
            DsModule.moduleLoad[_this.modulePath]=true;
            _this.resComplete();
        }
    };

    if(obj.module){
        _this.debug("加载["+_this.modulePath+"]中引入的模块["+obj.module+"]完成");
        new Module(obj.module,function(){
            if (obj.import != null) {
                for (var i = 0; i < obj.import.length; i++) {
                    this._eachImport(obj.import[i]);
                }
            }
            callback();
        });
        return;
    }
    var resArrayUrl = obj.url;
    if (resArrayUrl.lastIndexOf(".css") != -1) {
        _this.debug("加载["+_this.modulePath+"]中引入的CSS["+resArrayUrl+"]完成");
        this._loadCssRes(resArrayUrl, function () {
            if (obj.import != null) {
                for (var i = 0; i < obj.import.length; i++) {
                    this._eachImport(obj.import[i]);
                }
            }
            callback();
        });
    } else if (resArrayUrl.lastIndexOf(".js") != -1) {
        _this.debug("加载["+_this.modulePath+"]中引入的JS["+resArrayUrl+"]完成");
        this.improtJs(resArrayUrl, function () {
            if (obj.import != null) {
                for (var i = 0; i < obj.import.length; i++) {
                    this._eachImport(obj.import[i]);
                }
            }
            callback();
        });
    }


};


/**
 * 执行函数
 */
Module.prototype._execFun=function(data){
    var _this=this;
    _this.remove();
    this.setCacheData();
    if (_this.before != null) {
        data=_this.before.call(_this,data);
    }
    _this.selfDom = DsModule._stringToChildNodes(DsTemplate.exec(_this.resultHtml, data),_this);
    _this.parentDom.appendChild(_this.selfDom);
    if(_this.id){
        DsModule.moduleId[_this.id] = this;
    }
    if (_this.after != null) {
        _this.after.call(_this,data);
    }
    _this.bind(data);
    DsModule.dataListener(_this);
    _this.loadComplete();
}
/**
 * 引入依赖文件
 * @param resArray
 * @private
 */
Module.prototype._import = function (resArray) {
    var _this = this;
    _this.importSum = 0;
    for (var i = 0; i < resArray.length; i++) {
        _this._eachImportCount(resArray[i]);
    }
    if (_this.importSum == _this.importCount) {
        _this.debug("加载["+_this.modulePath+"]所有资源完成");
        DsModule.moduleLoad[_this.modulePath]=true;
        _this.resComplete();
        return;
    }
    for (var i = 0; i < resArray.length; i++) {
        _this._eachImport(resArray[i]);
    }
};

/**
 * 开始加载模块资源
 * @private
 */
Module.prototype._load = function () {
    var _this = this;
    var callback = function () {
        _this.resLoadCount++;
        if (_this.resLoadSum == _this.resLoadCount) {
            _this.debug("加载["+_this.modulePath+"]本模块的资源完成");
            _this._callJsObj.call(_this);
        }
    };
    _this.resLoadSum = 2;
    _this._loadJsRes(this.resJsUrl, callback); //模块内的js使用文本方式获取
    _this._loadHtmlRes(this.resHtmlUrl, callback);
};

/**
 * 加载css文件
 * @param url
 * @param callback
 * @private
 */
Module.prototype._loadCssRes = function (url, callback) {
    var _this = this;
    url = DsModule._getResUrl(url);
    if (DsModule.cacheCss[url] != null) {
        callback.call(_this);
        return;
    }
    var link = document.createElement("link");
    link.type = "text/css";
    link.rel = "stylesheet";
    link.onload = function () {
        DsModule.cacheCss[url] = true;
        callback.call(_this);
    };
    link.href = url;
    document.getElementsByTagName("head")[0].appendChild(link);
};

/**
 * 引入js文件
 * @param url
 * @param callback
 */
Module.prototype.improtJs = function (url, callback) {
    var _this = this;
    url = DsModule._getResUrl(url);
    if (DsModule.importJs[url] != null) {
        callback.call(_this);
        return;
    }
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    if (DsModule.ieVersion != null && DsModule.ieVersion <= 8) {
        script.onreadystatechange = function () {
            DsModule.importJs[url] = true;
            callback.call(_this);
        };
    } else {
        script.onload = function () {
            DsModule.importJs[url] = true;
            callback.call(_this);
        };
    }
    head.appendChild(script);
};
/**
 * 加载html 文件
 * @param url
 * @param callback
 * @private
 */
Module.prototype._loadHtmlRes = function (url, callback) {
    var _this = this;
    url = DsModule._getResUrl(url);
    if (DsModule.cacheHtml[url] != null) {
        _this.resultHtml = DsModule._getModuleHtml(_this.moduleName, DsModule.cacheHtml[url]);
        callback.call(_this);
        return;
    }
    DsModule._getRes(url, function (data) {
        DsModule.cacheHtml[url] = data;
        _this.resultHtml = DsModule._getModuleHtml(_this.moduleName, data);
        callback.call(_this);
    });
};

/**
 * 加载js 文件
 * @param url
 * @param callback
 * @private
 */
Module.prototype._loadJsRes = function (url, callback) {
    var _this = this;
    url = DsModule._getResUrl(url);
    if (DsModule.cacheJs[url] != null) {
        var jsObj = eval("0," + DsModule.cacheJs[url]).call(_this);
        for (var key in jsObj) {
            _this[key] = jsObj[key];
        }
        callback.call(_this);
        return;
    }
    DsModule._getRes(url, function (data) {
        DsModule.cacheJs[url] = data;
        var jsObj = eval("0," + data).call(_this);
        for (var key in jsObj) {
            _this[key] = jsObj[key];
        }
        callback.call(_this);
    });
};



/**
 * 重新加载模块，包括数据
 */
Module.prototype.reload = function () {
    var _this = this;
    var reload = function () {
        _this.remove();
        var data=DsModule.copy(_this.data);
        _this._execFun(data)
    }
    if (_this.isLoadComplete()) {
        reload();
        return;
    }
    _this.loadCompleteFun.push(reload);
};

Module.prototype.call=function(callback){
    if (this.isLoadComplete()) {
        callback(this);
        return;
    }
    this.loadCompleteFun.push(callback);
}

/**
 * 删除自己
 */
Module.prototype.remove = function () {
    if(this.id){
        DsModule.moduleId[this.id] = null;
    }
    if (this.selfDom != null) {
        this.parentDom.removeChild(this.selfDom);
        this.selfDom=null;
    }
};

/**
 * 表单转成键值对
 * @param className
 * @returns {{}}
 */
Module.prototype.toMap = function (className) {
    var data = {};
    this.$(className).each(function () {
        if($(this).attr("type")=="checkbox"){
            data[$(this).attr("name")] = $(this).is(':checked');
        }else{
            data[$(this).attr("name")] = $(this).val();
        }
    });
    return data;
};

/**
 * 加载到页面后
 */
Module.prototype.loadComplete = function () {
    this.loadCount++;
    while (this.loadCompleteFun.length > 0) {
        var deleteFun=this.loadCompleteFun[0];
        this.loadCompleteFun.splice(0, 1);
        deleteFun(this);
    }
}


/**
 * 是否加载完成
 */
Module.prototype.isLoadComplete = function () {
    if (this.loadCount > 0) {
        return true;
    }
    return false;
};



